package com.jwgf.queueprogramflash;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

public class HexParser {

    private List<HexBlock> listBlock = new ArrayList<HexBlock>();
    private HexBlock block;

    public void parseFile(String fileName) {
        FileReader in = null;
        long fileSize = new File(fileName).length();
        long analysisSize = 0;
        try {
            in = new FileReader(fileName);
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

        BufferedReader bufReader = new BufferedReader(in);

        String strLine = null;
        int baseAddress = 0;
        int startAddress = 0;

        try {
            while ((strLine = bufReader.readLine()) != null) {
                analysisSize += strLine.length() + 2;//每行少一个\r\n
                strLine = strLine.substring(1, strLine.length() - 2);
                byte[] byteLine = hexStr2Bytes(strLine);
                int type = byteLine[3];
                switch (type) {
                    case 0://data
                        int offset = ((byteLine[1] & 0xff) << 8)
                                | (byteLine[2] & 0xff);
                        startAddress = baseAddress + offset;
                        if (!block.checkContinuity(startAddress)) {
                            listBlock.add(block);
                            block = new HexBlock(baseAddress);
                        }
                        block.Add(byteLine);
                        break;
                    case 1://end
                        addBlock(block);
                        break;
                    case 2://Extended Segment Address Record
                        baseAddress = ((byteLine[4] & 0xff) << 8)
                                | ((byteLine[5] & 0xff) << 4);
                        addBlock(block);
                        block = new HexBlock(baseAddress);
                        break;
                    case 4://Extended LinearAddress Record
                        baseAddress = ((byteLine[4] & 0xff) << 24)
                                | ((byteLine[5] & 0xff) << 16);
                        addBlock(block);
                        block = new HexBlock(baseAddress);
                        break;
                }

            }


        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                bufReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public List<HexPage> splitPage(int pageSize) {
        List<HexPage> listPage = new ArrayList<HexPage>();
        for (HexBlock block : listBlock) {
            listPage.addAll(block.splitPage(pageSize));
        }
        return listPage;
    }

    private byte[] hexStr2Bytes(String src) {
        /* 对输入值进行规范化整理 */
        src = src.trim().replace(" ", "").toUpperCase(Locale.US);
        // 处理值初始化
        int m = 0, n = 0;
        int iLen = src.length() / 2; // 计算长度
        byte[] ret = new byte[iLen]; // 分配存储空间

        for (int i = 0; i < iLen; i++) {
            m = i * 2 + 1;
            n = m + 1;
            ret[i] = (byte) (Integer.decode("0x" + src.substring(i * 2, m)
                    + src.substring(m, n)) & 0xFF);
        }
        return ret;
    }

    private void addBlock(HexBlock block) {
        if (block != null && block.getBlockSize() > 0) {
            listBlock.add(block);
        }
    }
}
